package com.jumi.microservice.transfers;

import com.jumi.microservice.config.WxPayConfig;
import com.jumi.microservice.constant.TransferEnum;
import com.jumi.microservice.dto.PayTransferQueryRequest;
import com.jumi.microservice.dto.PayTransferRequest;
import com.jumi.microservice.transfers.common.BaseTransfer;
import com.jumi.microservice.transfers.common.Context;
import com.jumi.microservice.utils.ClientCustomSsl;
import com.jumi.microservice.utils.WxBuildRequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @author Scw
 * @Date 2019-09-29 09:38
 */

@Component
public class WxPayTransfer extends BaseTransfer {
    private Logger log = LoggerFactory.getLogger(WxPayTransfer.class);
    @Resource
    private WxPayConfig wxPayConfig;
    @Resource
    private ClientCustomSsl clientCustomSsl;

    @Override
    public Context createContext(PayTransferRequest request) {
        SortedMap<String, Object> parameters = new TreeMap<>();
        parameters.put("mch_appid", wxPayConfig.getAppId());
        parameters.put("mchid", wxPayConfig.getMchId());
        parameters.put("device_info", "WEB");
        parameters.put("nonce_str", WxBuildRequestUtil.getNonceStr());
        parameters.put("partner_trade_no", request.getOrderSn());
        parameters.put("openid", request.getAccountId());
        parameters.put("check_name", "NO_CHECK");
        parameters.put("re_user_name", request.getRealName());
        parameters.put("amount", request.getAmount());
        parameters.put("desc", request.getDesc());
        parameters.put("spbill_create_ip", request.getCreateIp());
        parameters.put("sign", WxBuildRequestUtil.createSign(parameters, wxPayConfig.getKey()));
        Context context = new Context();
        context.setParameters(parameters);
        return context;
    }

    @Override
    public Map<String, String> doProcess(Context context) {
        SortedMap<String, Object> parameters = context.getParameters();
        String requestXml = WxBuildRequestUtil.getRequestXml(parameters);
        String resultXml = clientCustomSsl.doPost(wxPayConfig.getTransferUrl(), requestXml);
        Map<String, String> map = WxBuildRequestUtil.doXMLParse(resultXml);
        //返回信息接收
        Map<String, String> returnMap = new HashMap<>();
        String params = "{" +
                "\"amount\":\"" + parameters.get("amount") +
                "\",\"check_name\":\"" + parameters.get("check_name") +
                "\",\"desc\":\"" + parameters.get("desc") +
                "\",\"device_info\":\"" + parameters.get("device_info") +
                "\",\"mch_appid\":\"" + parameters.get("mch_appid") +
                "\",\"mchid\":\"" + parameters.get("mchid") +
                "\",\"nonce_str\":\"" + parameters.get("nonce_str") +
                "\",\"openid\":\"" + parameters.get("openid") +
                "\",\"partner_trade_no\":\"" + parameters.get("partner_trade_no") +
                "\",\"sign\":\"" + parameters.get("sign") +
                "\",\"spbill_create_ip\":\"" + parameters.get("spbill_create_ip")
                + "\"}";
        returnMap.put("parameters", params);
        returnMap.put("return_code", map.get("return_code"));
        returnMap.put("return_msg", map.get("return_msg"));
        returnMap.put("result_code", map.get("result_code"));
        if ("SUCCESS".equals(map.get("result_code"))) {
            returnMap.put("partner_trade_no", map.get("partner_trade_no"));
            returnMap.put("payment_no", map.get("payment_no"));
            returnMap.put("payment_time", map.get("payment_time"));
        } else {
            returnMap.put("err_code", map.get("err_code"));
            returnMap.put("err_code_des", map.get("err_code_des"));
        }
        return returnMap;
    }

    @Override
    public Integer getType() {
        return TransferEnum.WX_PAY_TRANSFER.getCode();
    }

    /**
     * 转账查询接口
     */
    @Override
    public String transferQuery(PayTransferQueryRequest payTransferQueryRequest) {
        String transferQueryResult;
        SortedMap<String, Object> parameters = new TreeMap<String, Object>();
        parameters.put("appid", wxPayConfig.getAppId());
        parameters.put("mch_id", wxPayConfig.getMchId());
        parameters.put("nonce_str", payTransferQueryRequest.getNonceStr());
        parameters.put("partner_trade_no", payTransferQueryRequest.getPartnerTradeNo());
        parameters.put("sign", WxBuildRequestUtil.createSign(parameters, wxPayConfig.getKey()));
        String requestXml = WxBuildRequestUtil.getRequestXml(parameters);
        String resultXml = clientCustomSsl.doPost(wxPayConfig.getTransferInfoUrl(), requestXml);
        Map<String, String> map = WxBuildRequestUtil.doXMLParse(resultXml);

        //返回信息接收
        Map<String, String> returnMap = new HashMap<>();
        String params = "{" +
                "\"appid\":\"" + parameters.get("appid") +
                "\",\"mch_id\":\"" + parameters.get("mch_id") +
                "\",\"nonce_str\":\"" + parameters.get("nonce_str") +
                "\",\"sign\":\"" + parameters.get("sign") +
                "\",\"partner_trade_no\":\"" + parameters.get("partner_trade_no")
                + "\"}";
        returnMap.put("parameters", params);
        returnMap.put("return_code", map.get("return_code"));
        returnMap.put("return_msg", map.get("return_msg"));
        returnMap.put("result_code", map.get("result_code"));
        if ("SUCCESS".equals(map.get("result_code"))) {
            returnMap.put("partner_trade_no", map.get("partner_trade_no"));
            returnMap.put("appid", map.get("appid"));
            returnMap.put("mch_id", map.get("mch_id"));
            returnMap.put("detail_id", map.get("detail_id"));
            returnMap.put("status", map.get("status"));
            returnMap.put("reason", map.get("reason"));
            returnMap.put("openid", map.get("openid"));
            returnMap.put("transfer_name", map.get("transfer_name"));
            returnMap.put("payment_amount", map.get("payment_amount"));
            returnMap.put("transfer_time", map.get("transfer_time"));
            returnMap.put("payment_time", map.get("payment_time"));
            returnMap.put("desc", map.get("desc"));
        } else {
            returnMap.put("err_code", map.get("err_code"));
            returnMap.put("err_code_des", map.get("err_code_des"));
        }
        transferQueryResult = "查询结果：" + returnMap.toString();
        log.info("查询结果：{}", transferQueryResult);
        return transferQueryResult;
    }
}

